package br.com.sisat.persistencia.DAO;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import br.com.sisat.modelo.EspecialidadeDTO;
import br.com.sisat.modelo.TerapeutaDTO;
import br.com.sisat.persistencia.conexao.ConnectionProvider;
import br.com.sisat.util.ObjectUtil;

public class TerapeutaDAO {

	private static TerapeutaDAO dao;
	
	public static TerapeutaDAO getInstance(){
		if(ObjectUtil.isEmpty(dao)){
			dao = new TerapeutaDAO();
		}
		return dao;
	}
	
	private void preecherPkPessoa (TerapeutaDTO terapeuta, Connection conn)throws Exception{
		
		String sql = "select nextval ('sat.pessoa_id_pessoa_seq_1')";
		PreparedStatement ps = conn.prepareStatement(sql);
		ResultSet rs = ps.executeQuery();
		rs.next();
		terapeuta.setIdPessoa(rs.getLong(1));
	}
	
	private void preecherPkTerapeuta (TerapeutaDTO terapeuta, Connection conn)throws Exception{
		
		String sql = "select nextval ('sat.terapeuta_id_terapeuta_seq_1')";
		PreparedStatement ps = conn.prepareStatement(sql);
		ResultSet rs = ps.executeQuery();
		rs.next();
		terapeuta.setIdTerapeuta(rs.getLong(1));
	}
	
	public List<EspecialidadeDTO> recuperarEspecialidades() throws Exception {
		List<EspecialidadeDTO> especialidades = new ArrayList<EspecialidadeDTO>();
		String sql = " SELECT id_especialidade, nome FROM sat.especialidade order by id_especialidade;";
		Connection conn = ConnectionProvider.getDefaultConnection();
		PreparedStatement ps = conn.prepareStatement(sql);
		ResultSet rs = ps.executeQuery();
		while(rs.next()){
			EspecialidadeDTO especialidade = new EspecialidadeDTO();
			especialidade.setIdEspecialidade(rs.getLong("id_especialidade"));
			especialidade.setNoEspecialidade(rs.getString("nome"));
			especialidades.add(especialidade);
		}
		conn.close();
		return especialidades;
	}

	public List<TerapeutaDTO> recuperarTerapeutas() throws Exception {
		List<TerapeutaDTO> terapeutas = new ArrayList<TerapeutaDTO>();
		String sql = " SELECT terapeuta.id_pessoa, pessoa.nome" +
					 " FROM sat.terapeuta terapeuta" +
					 " join sat.pessoa pessoa on (terapeuta.id_pessoa = pessoa.id_pessoa) order by terapeuta.id_pessoa;";
		Connection conn = ConnectionProvider.getDefaultConnection();
		PreparedStatement ps = conn.prepareStatement(sql);
		ResultSet rs = ps.executeQuery();
		while(rs.next()){
			TerapeutaDTO terapeuta = new TerapeutaDTO();
			terapeuta.setIdTerapeuta(rs.getLong("id_pessoa"));
			terapeuta.setNoTerapeuta(rs.getString("nome"));
			terapeutas.add(terapeuta);
		}
		conn.close();
		return terapeutas;
	}


	public List<TerapeutaDTO> executarConsultar(TerapeutaDTO terapeutaDTO) throws Exception {
		List<TerapeutaDTO> terapeutas = new ArrayList<TerapeutaDTO>();
		String sql = "SELECT DISTINCT pessoa.id_pessoa, pessoa.nome, pessoa.cpf, pessoa.email, pessoa.endereco, " +
		 "pessoa.bairro, pessoa.municipio, pessoa.uf, pessoa.cep, pessoa.telefone, " +
		 "pessoa.celular, pessoa.rg  " +
		 "FROM sat.pessoa pessoa " +
		 "join sat.terapeuta terapeuta on (pessoa.id_pessoa = terapeuta.id_pessoa) " +
		 "join sat.especialidade especialidade on (terapeuta.id_especialidade = especialidade.id_especialidade) " +
		 "where 1 = 1";
		
		
		if(!ObjectUtil.isEmpty(terapeutaDTO.getIdPessoa()) && terapeutaDTO.getIdPessoa() != 0){
			sql =  sql + " and pessoa.id_pessoa = " + terapeutaDTO.getIdPessoa().toString();
		}
		if(!ObjectUtil.isEmpty(terapeutaDTO.getIdEspecialidade()) && terapeutaDTO.getIdEspecialidade() != 0){
			sql =  sql + " and especialidade.id_especialidade = " + terapeutaDTO.getIdEspecialidade().toString();
		}
		if(!ObjectUtil.isEmpty(terapeutaDTO.getNoTerapeuta()) && terapeutaDTO.getNoTerapeuta().length() > 0){
			sql =  sql + " and upper(pessoa.nome) like  upper('" + terapeutaDTO.getNoTerapeuta().toUpperCase() + "%')";
		}
			
		Connection conn = ConnectionProvider.getDefaultConnection();
		sql += " order by pessoa.nome";
		PreparedStatement ps = conn.prepareStatement(sql);
		ResultSet rs = ps.executeQuery();
		while(rs.next()){
			TerapeutaDTO terapeutaConsulta = new TerapeutaDTO();
			terapeutaConsulta.setIdPessoa		(rs.getLong("id_pessoa"));
			terapeutaConsulta.setNoTerapeuta		(rs.getString("nome"));
			terapeutaConsulta.setDeCpf			(rs.getString("cpf"));
			terapeutaConsulta.setDeEmail			(rs.getString("email"));
			terapeutaConsulta.setDeEndereco		(rs.getString("endereco"));
			terapeutaConsulta.setDeBairro		(rs.getString("bairro"));
			terapeutaConsulta.setDeMunicipio		(rs.getString("municipio"));
			terapeutaConsulta.setSgUf			(rs.getString("uf"));
			terapeutaConsulta.setDeCep			(rs.getString("cep"));
			terapeutaConsulta.setDeFoneResidencial(rs.getString("telefone"));
			terapeutaConsulta.setDeFoneCelular	(rs.getString("celular"));
			terapeutaConsulta.setDeRg			(rs.getString("rg"));
			//tera.setNoEspecialidade	(rs.getString("especialidade"));
			
			recuperaEspecialidades(terapeutaConsulta,conn);
			
			terapeutas.add(terapeutaConsulta);
		}
		
		
		
		
		conn.close();
		return terapeutas;
	}


	private void recuperaEspecialidades(TerapeutaDTO terapeuta,
			Connection conn) throws Exception{
		String sql = "	SELECT esp.id_especialidade, esp.nome, id_terapeuta, "+
					 " (SELECT COUNT(*) FROM sat.consulta cons "+
                     " 			WHERE cons.id_terapeuta = tera.id_terapeuta) as consultas "+
				     "	FROM sat.especialidade esp "+
				     "	JOIN sat.terapeuta tera ON (tera.id_especialidade = esp.id_especialidade) "+
				     "  WHERE tera.id_pessoa = ?";
		
		PreparedStatement ps = conn.prepareStatement(sql);
		ps.setLong(1, terapeuta.getIdPessoa());
		ResultSet rs = ps.executeQuery();
		while(rs.next()){
			EspecialidadeDTO espec = new EspecialidadeDTO();
			espec.setIdEspecialidade(rs.getLong("id_especialidade"));
			espec.setNoEspecialidade(rs.getString("nome"));
			espec.setIdTerapeuta(rs.getLong("id_terapeuta"));
			espec.setConsultas(rs.getLong("consultas"));
			terapeuta.getEspecialidades().add(espec);
		}
		
	}

	public void executarExcluir(TerapeutaDTO terapeutaDTO) throws Exception {
		Connection conn = ConnectionProvider.getDefaultConnection();
		String sql = "DELETE FROM sat.pessoa WHERE id_pessoa = " + terapeutaDTO.getIdPessoa();
		PreparedStatement ps = conn.prepareStatement(sql);
		
		String sql2 = "DELETE FROM sat.terapeuta WHERE id_pessoa = " + terapeutaDTO.getIdPessoa();
		PreparedStatement ps2 = conn.prepareStatement(sql2);
		
		ps.executeUpdate();
		ps2.executeUpdate();
		conn.commit();
		ps.close();
		ps2.close();
	}


	public void executarAlterar(TerapeutaDTO pessoa) throws Exception {
					
			String sql = "UPDATE sat.pessoa " +
			"SET nome = ?, cpf = ?, email = ?, endereco = ?, bairro = ?, municipio = ?, " +
			"uf = ?, cep = ?, telefone = ?, celular = ?, rg = ? " +
			"WHERE id_pessoa = " + pessoa.getIdPessoa().toString();
			Connection conn = ConnectionProvider.getDefaultConnection();
			PreparedStatement ps = conn.prepareStatement(sql);
			int index = 1;
			ps.setString(index++, pessoa.getNoTerapeuta());
			ps.setString(index++, pessoa.getDeCpf());
			ps.setString(index++, pessoa.getDeEmail());
			ps.setString(index++, pessoa.getDeEndereco());
			ps.setString(index++, pessoa.getDeBairro());
			ps.setString(index++, pessoa.getDeMunicipio());
			ps.setString(index++, pessoa.getSgUf());
			ps.setString(index++, pessoa.getDeCep());
			ps.setString(index++, pessoa.getDeFoneResidencial());
			ps.setString(index++, pessoa.getDeFoneCelular());
			ps.setString(index++, pessoa.getDeRg());
			
			ps.executeUpdate();
			ps.close();
			
			for(EspecialidadeDTO especialidade: pessoa.getEspecialidadesARemover()){
				desvinculaEspecialidade(especialidade, conn);
			}
			
			for(EspecialidadeDTO especialidade: pessoa.getEspecialidades()){
				if(ObjectUtil.isEmpty(especialidade.getIdTerapeuta())){
					vinculaEspecialidade(especialidade.getIdEspecialidade(), pessoa.getIdPessoa(),conn);
				}
			}
			
			conn.commit();
			
			
				
	}

	public void executarIncluir(TerapeutaDTO pessoa) throws Exception {
		
		String sql = "INSERT INTO sat.pessoa " +
		"(id_pessoa, nome, cpf, email, endereco, bairro, municipio, uf, " +
		"cep, telefone, celular, rg) " +
		"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ";
		Connection conn = ConnectionProvider.getDefaultConnection();
		PreparedStatement ps = conn.prepareStatement(sql);
		int index = 1;
		
		preecherPkPessoa(pessoa, conn);
		ps.setLong 		(index++, pessoa.getIdPessoa());
		ps.setString	(index++, pessoa.getNoTerapeuta());
		ps.setString	(index++, pessoa.getDeCpf());
		ps.setString	(index++, pessoa.getDeEmail());
		ps.setString 	(index++, pessoa.getDeEndereco());
		ps.setString 	(index++, pessoa.getDeBairro());
		ps.setString 	(index++, pessoa.getDeMunicipio());
		ps.setString 	(index++, pessoa.getSgUf());
		ps.setString 	(index++, pessoa.getDeCep());
		ps.setString 	(index++, pessoa.getDeFoneResidencial());
		ps.setString 	(index++, pessoa.getDeFoneCelular());
		ps.setString 	(index++, pessoa.getDeRg());
		
		ps.executeUpdate();
		ps.close();
		
		
		
		for(EspecialidadeDTO especialidade: pessoa.getEspecialidades()){
			vinculaEspecialidade(especialidade.getIdEspecialidade(), pessoa.getIdPessoa(),conn);
		}
		
		
		conn.commit();
		
		
	}
	
	private void desvinculaEspecialidade(EspecialidadeDTO especialidade,Connection conn) throws Exception{
		PreparedStatement ps = conn.prepareStatement("DELETE FROM sat.terapeuta WHERE id_terapeuta = ?");
		ps.setLong(1, especialidade.getIdTerapeuta());
		ps.executeUpdate();
		ps.close();
	}

	private void vinculaEspecialidade(Long idEspecialidade, Long idPessoa,
			Connection conn) throws Exception{
				String sqlTerapeuta = "INSERT INTO sat.terapeuta (id_terapeuta, " +
						"id_especialidade, id_pessoa) " +
						"VALUES (?, ?, ?); " ;
				PreparedStatement psTerapeuta = conn.prepareStatement(sqlTerapeuta);
				int index = 1;
				TerapeutaDTO terapeuta = new TerapeutaDTO();
				terapeuta.setIdPessoa(idPessoa);
				terapeuta.setIdEspecialidade(idEspecialidade);
				preecherPkTerapeuta(terapeuta, conn);
				psTerapeuta.setLong(index++, terapeuta.getIdTerapeuta());
				psTerapeuta.setLong(index++, terapeuta.getIdEspecialidade());
				psTerapeuta.setLong(index++, terapeuta.getIdPessoa());
				psTerapeuta.executeUpdate();
				psTerapeuta.close();
	}

	public List<TerapeutaDTO> verificaDependencia (TerapeutaDTO terapeuta) throws Exception{
		Connection conn = ConnectionProvider.getDefaultConnection();
		List<TerapeutaDTO> dependenciaTerapeutas = new ArrayList<TerapeutaDTO>();
		String sql = "SELECT cons.id_pessoa from sat.consulta cons "+
					 " join sat.terapeuta ter on (cons.id_terapeuta = ter.id_terapeuta) "+
					 " where ter.id_pessoa = " 
		+ terapeuta.getIdPessoa().toString();
		PreparedStatement ps = conn.prepareStatement(sql);
		ResultSet rs = ps.executeQuery();
		while (rs.next()){
			TerapeutaDTO teraResultado = new TerapeutaDTO();
			teraResultado.setIdPessoa(rs.getLong("id_pessoa"));
			dependenciaTerapeutas.add(teraResultado);
		}
		return dependenciaTerapeutas;
	}
}

